package generator

import (
	"RoccBlog/model"
	"bytes"
	"embed"
	"errors"
	"github.com/gin-gonic/gin"
	"strings"
	"text/template"
)

//go:embed template
var templateFs embed.FS
var templateInstance *template.Template

// 首字母小写
func firstToLower(field string) string {
	return strings.ToLower(field[:1]) + field[1:]
}

// 字段转小写下划线
func fieldToLineLower(field string) string {
	var strArr = make([]int32, 0)
	for i, v := range field {
		if v >= 'a' && v <= 'z' {
			strArr = append(strArr, v)
			continue
		}
		if i == 0 {
			strArr = append(strArr, v+32)
			continue
		}
		strArr = append(strArr, '_', v+32)
	}

	return string(strArr)
}

func init() {
	//不为空则返回
	if templateInstance != nil {
		return
	}

	templateInstance = template.New("generator").Funcs(template.FuncMap{
		"firstToLower":     firstToLower,
		"fieldToLineLower": fieldToLineLower,
	})

}

func Sigle(generatorTable model.GeneratorTable) (rlt any, err error) {

	//捕获异常
	defer func() {
		catchData := recover()
		if catchData != nil {
			err = catchData.(error)
		}
	}()

	var hand = func(msg string, err error) {
		if err != nil {
			panic(errors.New(msg + err.Error()))
		}
	}

	//controller 控制层生成
	controllerFs, err := templateInstance.ParseFS(templateFs, "template/sigle/controller.tmpl")
	hand("生成controller失败", err)
	bufStr := bytes.Buffer{}
	err = controllerFs.ExecuteTemplate(&bufStr, "controller.tmpl", generatorTable)
	hand("解析controller失败", err)
	controllerStr := bufStr.String()
	bufStr.Reset()

	//service 业务层生成
	serviceFs, err := templateInstance.ParseFS(templateFs, "template/sigle/service.tmpl")
	hand("生成service失败", err)
	err = serviceFs.ExecuteTemplate(&bufStr, "service.tmpl", generatorTable)
	hand("解析service失败", err)
	serviceStr := bufStr.String()
	bufStr.Reset()

	//repository 持久层生成
	repositoryFs, err := templateInstance.ParseFS(templateFs, "template/sigle/repository.tmpl")
	hand("生成repository失败", err)
	err = repositoryFs.ExecuteTemplate(&bufStr, "repository.tmpl", generatorTable)
	hand("解析repository失败", err)
	repositoryStr := bufStr.String()
	bufStr.Reset()

	//model生成
	modelFs, err := templateInstance.ParseFS(templateFs, "template/sigle/model.tmpl")
	hand("生成repository失败", err)
	err = modelFs.ExecuteTemplate(&bufStr, "model.tmpl", generatorTable)
	hand("解析repository失败", err)
	modelStr := bufStr.String()
	bufStr.Reset()

	//api 生成
	apiFs, err := templateInstance.ParseFS(templateFs, "template/sigle/api.tmpl")
	hand("生成repository失败", err)
	err = apiFs.ExecuteTemplate(&bufStr, "api.tmpl", generatorTable)
	hand("解析repository失败", err)
	apiStr := bufStr.String()
	bufStr.Reset()

	//view 生成
	viewFs, err := templateInstance.ParseFS(templateFs, "template/sigle/view.tmpl")
	hand("生成repository失败", err)
	err = viewFs.ExecuteTemplate(&bufStr, "view.tmpl", generatorTable)
	hand("解析repository失败", err)
	viewStr := bufStr.String()
	bufStr.Reset()

	data := gin.H{
		fieldToLineLower(generatorTable.StructName) + "_controller.go": controllerStr,
		fieldToLineLower(generatorTable.StructName) + "_service.go":    serviceStr,
		fieldToLineLower(generatorTable.StructName) + "_repository.go": repositoryStr,
		fieldToLineLower(generatorTable.StructName) + ".go":            modelStr,
		firstToLower(generatorTable.StructName) + ".ts":                apiStr,
		generatorTable.StructName + "View.vue":                         viewStr,
	}
	if generatorTable.EnableSearch {
		//req_resp持久层生成
		reqFs, err := templateInstance.ParseFS(templateFs, "template/sigle/req_resp.tmpl")
		hand("生成req_resp失败", err)
		err = reqFs.ExecuteTemplate(&bufStr, "req_resp.tmpl", generatorTable)
		hand("解析req_resp失败", err)
		reqStr := bufStr.String()
		data[fieldToLineLower(generatorTable.StructName)+"_req_resp.go"] = reqStr
		bufStr.Reset()
	}

	rlt = data

	return
}
